/*
 * session.h
 * This file is part of gURL
 *
 * Copyright (C) 2013 - Aleksey Konovalov
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Library General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef SESSION_H
#define SESSION_H

#include <curl/curl.h>
#include "encoding.h"
#include <gtk/gtk.h>

#define SESSION_TYPE (session_get_type())
#define SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SESSION_TYPE, Session))
#define SESSION_CLASS(cl) (G_TYPE_CHECK_CLASS_CAST((cl), SESSION_TYPE, SessionClass))
#define IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SESSION_TYPE))
#define IS_SESSION_CLASS(cl) (G_TYPE_CHECK_CLASS_TYPE((cl), SESSION_TYPE))
#define SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
                                SESSION_TYPE, SessionClass))

typedef struct _SessionClass SessionClass;
typedef struct _Session Session;

struct _Session {
    GObject parent;

    struct {
        GString* url;
        GString* body;
        GString* headers;
        Encoding body_encoding;
    } request;

    struct {
        long status;
        GString* headers;
        GString* body;
        GString* content_type;
        Encoding content_encoding;
    } response;

    struct {
        double total_time;
        double namelookup_time;
        double connect_time;
        double pretransfer_time;
        const char* str_error;
    } statistics;

    /*< private > */
    struct curl_slist* cURLheaders;
    size_t body_sended_bytes; // for async body sending
};

struct _SessionClass {
    GObjectClass parent_class;

    /* curl multi handle */
    CURLM* curlm;
    /* curl handles count */
    int curl_handle_count;
};

typedef enum {
    mGET,
    mPOST,
    mHEAD,
    mDELETE,
    mPUT,
} method_type;

typedef enum {
   uREQUEST_HEADERS,
   uRESPONSE_HEADERS,
   uRESPONSE_BODY,
   uRESPONSE_STATUS
} updated_information;

GType session_get_type();

Session* session_new(method_type mtype, const char* url,
                     const char* headers, const char* body, gsize body_len,
                     Encoding body_encoding);
const GString* session_get_request_url(Session* session);
const GString* session_get_request_headers(Session* session);
const GString* session_get_request_body(Session* session);
Encoding session_get_request_body_encoding(Session* session);
long session_get_http_status(Session* session);

const GString* session_get_response_headers(Session* session);
const GString* session_get_response_body(Session* session);
const GString* session_get_response_content_type(Session* session);
Encoding session_get_response_content_encoding(Session* session);
void session_set_response_content_encoding(Session* session, Encoding enc);

#endif /* SESSION_H */
